#include "OneWire.h"
#include "intrins.h"

sbit OneWire_DQ = P1^4;

void Delay500us(void)		//@11.0592MHz
{
	unsigned char i, j;

	_nop_();	_nop_();
	i = 6;	j = 93;
	do
	{
		while (--j);
	} while (--i);
}

/*初始化
	主机 将总线拉低至少480us，然后释放总线，
	等待15~60us后，存在的 从机 会拉低总线60~240us以响应 主机
	之后 从机 将释放总线
*/
unsigned char OneWire_Init(void)
{
	unsigned char AckBit;
	unsigned char i;
	OneWire_DQ = 1; //先给总线置1	
	OneWire_DQ = 0; //再拉低总线500us
	Delay500us();
	
	OneWire_DQ = 1; //释放总线
	i = 191;	while (--i);	//延时70us
	AckBit = OneWire_DQ;	//读出I/O口电平,存放在AckBit
	
	Delay500us();	//时序图上也是至少480us
	return AckBit;	//应答位
}

/*发送一位
	主机将总线拉低60~120us，然后释放总线，表示发送0；
	主机将总线拉低1~15us，然后释放总线，表示发送1。
	从机 将在总线拉低30us后读取电平，整个时间片应大于60us
	*/
void OneWire_SendBit(unsigned char Bit)
{
	unsigned char i;
	OneWire_DQ = 0;			//先把总线拉低，因为初始化结束后总线是1
	i = 28;	 while (--i);	//延时10us
	OneWire_DQ = Bit;		//10us后将Bit送回总线,检测Bit看变化赋值，比较巧妙的思想
	i = 138; while (--i);	//延时50us
	OneWire_DQ = 1;			//最后释放总线
}

/*接收一位
	主机将总线拉低1~15us，然后释放总线，并在拉低后15us内读取总线电平（尽量贴近15us末尾）
	读取为低电平则为接收0，读取为高电平则为接收1，整个时间片应大于60us
	*/
unsigned char OneWire_ReceiveBit(void)
{
	unsigned char i;
	unsigned char Bit;
	OneWire_DQ = 0;			//先把总线拉低5us
	i = 11;	 while (--i);
	
	OneWire_DQ = 1;			//释放总线，如果数据是0，总线就会被拉低
	i = 11;	 while (--i);	//再延时5us
	Bit = OneWire_DQ;		//这时候再采样读取电平(如果读取到0代表从机给拉低了)
	i = 138; while (--i);	//最后延时50us，满足时序要求
	//结束后 从机 会自动释放总线 
	
	return Bit;
}

//发送一个字节，从低位到高位发送
void OneWire_SendByte(unsigned char Byte)
{	
	unsigned char i;
	for(i=0;i<8;i++)
	{
		OneWire_SendBit(Byte&(0x01<<i));
	}	
}

//接收一个字节，低位到高位依次取出
unsigned char OneWire_ReceiveByte(void)
{
	unsigned char i;
	unsigned char Byte = 0x00;
	for(i=0;i<8;i++)
	{
		//这个if判断，判断为0的时候，Byte当前位还是0，但是变量i正常++
		if (OneWire_ReceiveBit() ) 	//只有接收1才会执行下面的语句
		{Byte |= (0x01<<i);} 		//从低位到高位依次取出		
	}
	return Byte;
}








